package org.jeecg.modules.order.service;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.MutableTriple;
import org.apache.commons.lang3.tuple.Pair;
import org.jeecg.common.modules.doctor.entity.DoctorAccount;
import org.jeecg.common.modules.doctor.entity.DoctorAccountFlow;
import org.jeecg.common.modules.doctor.service.IDoctorAccountFlowService;
import org.jeecg.common.modules.doctor.service.IDoctorAccountService;
import org.jeecg.common.modules.doctor.service.IDoctorService;
import org.jeecg.common.modules.order.entity.OrderInfo;
import org.jeecg.common.modules.order.entity.PayOrder;
import org.jeecg.common.modules.order.service.IOrderInfoService;
import org.jeecg.common.modules.order.service.IPayOrderService;
import org.jeecg.common.modules.settlement.entity.Settlement;
import org.jeecg.common.modules.settlement.service.ISettlementService;
import org.jeecg.common.modules.sys.entity.SysAccount;
import org.jeecg.common.modules.sys.entity.SysAccountFlow;
import org.jeecg.common.modules.sys.service.ISysAccountFlowService;
import org.jeecg.common.modules.sys.service.ISysAccountService;
import org.jeecg.common.util.enums.AccountFlowTypeEnum;
import org.jeecg.common.util.enums.SysAccountFlowTypeEnum;
import org.jeecg.common.util.enums.SysAccountTypeEnum;
import org.jeecg.common.wx.WxRefundService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.weixin4j.pay.WeixinPayException;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Objects;

/**
 * @author guoyh
 * @ClassName OrderService
 * @Description
 * @since 2020/9/5 16:41
 **/
@Service
@Slf4j
public class AdminOrderService {

    @Resource
    private IPayOrderService payOrderService;
    @Resource
    private WxRefundService wxRefundService;
    @Resource
    private ISettlementService settlementService;
    @Resource
    private IOrderInfoService orderInfoService;
    @Resource
    private IDoctorAccountService doctorAccountService;
    @Resource
    private IDoctorAccountFlowService doctorAccountFlowService;
    @Resource
    private ISysAccountService sysAccountService;
    @Resource
    private ISysAccountFlowService sysAccountFlowService;
    @Resource
    private IDoctorService doctorService;

    /**
     * 后台操作退款（针对结算单）
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Pair<Boolean,String> refund(Long settlementId,String reason,String loginUser) throws Exception{
        Settlement settlement = settlementService.getById(settlementId);
        if (Objects.isNull(settlement)){
            return Pair.of(false,"未获取到结算单");
        }
        OrderInfo orderInfo = orderInfoService.getById(settlement.getRelationId());
        if (Objects.isNull(orderInfo)){
            return Pair.of(false,"未获取到订单信息");
        }
        DoctorAccount account = doctorAccountService.getByDoctorId(orderInfo.getDoctorId());
        if (Objects.isNull(account)){
            return Pair.of(false,"未获取到医生账户信息");
        }
        DoctorAccountFlow accountFlow = doctorAccountFlowService.getAccountFlow(account.getId(), AccountFlowTypeEnum.INCOME,settlementId.toString());
        if (Objects.isNull(accountFlow)){
            return Pair.of(false,"未获取到医生账户流水信息");
        }
        SysAccount sysAccount = sysAccountService.getOrCreateAccount(SysAccountTypeEnum.PLATFORM);
        if (Objects.isNull(sysAccount)){
            return Pair.of(false,"未获取到平台账户");
        }
        SysAccountFlow sysAccountFlow = sysAccountFlowService.getSysAccountFlow(sysAccount.getId(), SysAccountFlowTypeEnum.DOCTOR_SERVICE,settlementId.toString());
        if (Objects.isNull(sysAccountFlow)){
            return Pair.of(false,"未获取到平台账户流水信息");
        }
        //修改医生余额
        BigDecimal doctorAmount = accountFlow.getAmount().negate();
        doctorAccountService.changeBalance(orderInfo.getDoctorId(),doctorAmount,AccountFlowTypeEnum.REFUND,orderInfo.getId());
        //修改平台余额
        BigDecimal platformAmount = sysAccountFlow.getAmount().negate();
        sysAccountService.changeSysBalance(SysAccountTypeEnum.PLATFORM,SysAccountFlowTypeEnum.DOCTOR_REFUND_SERVICE,platformAmount,orderInfo.getId(),loginUser);

        try {
            Pair<Boolean,String> refundPair = doRefund(orderInfo,reason);
            if (!refundPair.getLeft()){
                return refundPair;
            }
        } catch (Exception e) {
            log.error("退款异常",e);
            throw e;
        }
        return Pair.of(true,null);
    }

    public Pair<Boolean,String> doRefund(OrderInfo orderInfo,String reason) throws WeixinPayException{
        PayOrder payOrder = payOrderService.getById(orderInfo.getPayOrderId());
//        PayOrder payOrder = payOrderService.getById("1433336550229946369");
        MutableTriple<Boolean,String, PayOrder> pair = payOrderService.initRefund(payOrder);
        if (!pair.getLeft()){
            log.error("{}无法退款{}",orderInfo.getId(),pair.getMiddle());
            return Pair.of(false,pair.getMiddle());
        }
        //退款
        wxRefundService.refund(pair.getRight(),payOrder.getThirdOrderCode(),orderInfo,payOrder,reason);

        return Pair.of(true,null);
    }

    public void doRefundNew() throws WeixinPayException{
        PayOrder payOrder = payOrderService.getById("1433310607142694913");
        OrderInfo orderInfo = orderInfoService.getById("1433310650331443202");
        String reason = "功能建设中，暂时不支持问诊。由此给您带来的不便，敬请谅解！";
        MutableTriple<Boolean,String, PayOrder> pair = payOrderService.initRefund(payOrder);
        if (!pair.getLeft()){
            log.error("{}无法退款{}","1433336616017604610",pair.getMiddle());
        }
        //退款
        wxRefundService.refund(pair.getRight(),payOrder.getThirdOrderCode(),orderInfo,payOrder,reason);

    }
}
